#include "stdafx.h"
#include "Win32Exception.h"
#include "CriticalSection.h"
#include "Logger.h"

#define LOG_SERVER_NAME NULL

using namespace std;
using namespace ISAPI_Python::Win32Helpers;

Logger::Logger(const string& logName) :
  EventSourceHandle( NULL ) {
	  EventSourceHandle = RegisterEventSourceA(LOG_SERVER_NAME, logName.c_str());
	  if(EventSourceHandle == (HANDLE)NULL || EventSourceHandle == (HANDLE)ERROR_ACCESS_DENIED) {
		  throw Win32Exception();
	  }
}

Logger::~Logger() throw() {
	DeregisterEventSource(EventSourceHandle);
}

Logger_ptr Logger::GetLogger(const string& loggerName) {
	static CriticalSection LoggersCriticalSection;
	static map<string, Logger_ptr> GlobalLoggers;

	Logger_ptr foundLogger = GlobalLoggers[loggerName];

	if(!foundLogger) {
		LoggersCriticalSection.Enter();
		
		foundLogger = GlobalLoggers[loggerName];
		
		if(!foundLogger) {
			foundLogger = Logger_ptr(new Logger(loggerName));
			GlobalLoggers[loggerName] = foundLogger;
		}

		LoggersCriticalSection.Leave();
	}

	return foundLogger;
}

void Logger::LogError(const string& message, WORD type) throw() {
	LPCSTR messages[1] = { message.c_str() };
	BOOL result = ReportEventA(EventSourceHandle, type, 0, 0, NULL, 1, 0, messages, NULL);
	if(!result) {
		_CrtDbgBreak(); //Throw a real exception here.
	}
}

void Logger::Error(const string& message) throw() {
	LogError(message, EVENTLOG_ERROR_TYPE);
}

void Logger::Warning(const string& message) throw() {
	LogError(message, EVENTLOG_WARNING_TYPE);
}

void Logger::Info(const string& message) throw() {
	LogError(message, EVENTLOG_INFORMATION_TYPE);
}